﻿// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "tests/cefclient/browser/root_window_win.h"

#include "include/base/cef_bind.h"
#include "include/base/cef_build.h"
#include "include/cef_app.h"
#include "tests/cefclient/browser/browser_window_osr_win.h"
#include "tests/cefclient/browser/browser_window_std_win.h"
#include "tests/cefclient/browser/main_context.h"
#include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/temp_window.h"
#include "tests/cefclient/browser/window_test_runner_win.h"
#include "tests/shared/browser/geometry_util.h"
#include "tests/shared/browser/main_message_loop.h"
#include "tests/shared/browser/util_win.h"
#include "tests/shared/common/client_switches.h"
#include <fstream>
#include <codecvt>
#include "include/cef_parser.h"
#include <conio.h> 
#include <Shlwapi.h>
#include <Shellapi.h>
#include "tests/cefclient/browser/protocol.h"
#include "include/cef_thread.h"
#include "tests/cefclient/browser/user_manager.h"
#include "tests/cefclient/browser/download_service.h"

#define MAX_URL_LENGTH 255
#define BUTTON_WIDTH 72
#define URLBAR_HEIGHT 24
static const  int  g_alpha_value = 240;
static const  int  g_upup_login_width = 335;
static const int g_upup_login_height = 430;
static const int g_qq_width = 500;
static const int g_qq_height = 400;
static const int g_bind_width = 335;
static const int g_bind_height = 430;
static const int g_offset = 20;
static HWND g_movehWnd = NULL; 
static WNDCLASS g_movewndclass;
static  bool g_dragWindow = false;
static POINT g_startpoint;
static POINT g_nowpoint;
static RECT g_clientrect;
static bool g_reach = false;
static bool g_resize = false;
static bool g_leftreach = false;
static bool g_rightreach = false;
static bool g_bottomreach = false;
static bool g_mouselpressed = false;
static HCURSOR g_cursor;
static HCURSOR g_arrowcursor;
static HCURSOR g_wecursor;
static HWND g_roothwnd;
//static COLORREF   bcolor = RGB(255, 180, 0); 
//static HBRUSH hbgbrush = CreateSolidBrush(bcolor);
static TCHAR g_classname[32];
static int g_wcount = 0; 
static const int g_default_store_w = 1025;
static const int g_default_store_h = 612;
static   bool g_isarrow = true; 
static  const int g_guide_w = 1200;
static const int g_guide_h = 716;
 
//CefRefPtr<CefV8Value> globalcallfun_ = CefV8Value::CreateArray(2);

namespace client {

	enum cursortype {
		arrow = 0,
		right = 1,
		bottom = 2,
		rb = 3
};

namespace {

// Message handler for the About box.
INT_PTR CALLBACK AboutWndProc(HWND hDlg,
                              UINT message,
                              WPARAM wParam,
                              LPARAM lParam) {
  UNREFERENCED_PARAMETER(lParam);
  switch (message) {
    case WM_INITDIALOG:
      return TRUE;

    case WM_COMMAND:
      if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
        EndDialog(hDlg, LOWORD(wParam));
        return TRUE;
      }
      break;
  }
  return FALSE;
}

int GetButtonWidth() {
  static int button_width = BUTTON_WIDTH;
  static bool initialized = false;

  if (!initialized) {
    button_width = LogicalToDevice(BUTTON_WIDTH, GetDeviceScaleFactor());
    initialized = true;
  }

  return button_width;
}

int GetURLBarHeight() {
  static int urlbar_height = URLBAR_HEIGHT;
  static bool initialized = false;

  if (!initialized) {
    urlbar_height = LogicalToDevice(URLBAR_HEIGHT, GetDeviceScaleFactor());
    initialized = true;
  }

  return urlbar_height;
}

}  // namespace

LRESULT CALLBACK TaskWinProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM IParam
);

LRESULT CALLBACK MoveWindowProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM IParam
);

RootWindowWin::RootWindowWin()
    : delegate_(NULL),
      with_controls_(false),
      with_osr_(false),
      is_popup_(false),
      start_rect_(),
      initialized_(false),
      hwnd_(NULL),
      draggable_region_(NULL),
      font_(NULL),
      back_hwnd_(NULL),
      forward_hwnd_(NULL),
      reload_hwnd_(NULL),
      stop_hwnd_(NULL),
      edit_hwnd_(NULL),
      edit_wndproc_old_(NULL),
      find_hwnd_(NULL),
      find_message_id_(0),
      find_wndproc_old_(NULL),
      find_state_(),
      find_next_(false),
      find_match_case_last_(false),
      window_destroyed_(false),
      browser_destroyed_(false),
	  tabid_(0),
	  gostep_(0),
	  has_set_parent_(false),
	  aftersome_play_hwnd_(0)
{
  find_buff_[0] = 0;

  // Create a HRGN representing the draggable window area.
  draggable_region_ = ::CreateRectRgn(0, 0, 0, 0);
}

RootWindowWin::~RootWindowWin() {
  REQUIRE_MAIN_THREAD();

  ::DeleteObject(draggable_region_);
  ::DeleteObject(font_);

  // The window and browser should already have been destroyed.
  DCHECK(window_destroyed_);
  DCHECK(browser_destroyed_);
}

void RootWindowWin::Init(RootWindow::Delegate* delegate,
                         bool with_controls,
                         bool with_osr,
                         const CefRect& bounds,
                         const CefBrowserSettings& settings,
                         const std::string& url) {
  DCHECK(delegate);
  DCHECK(!initialized_);

  delegate_ = delegate;
  with_controls_ = with_controls;
  with_osr_ = with_osr;

  start_rect_.left = bounds.x;
  start_rect_.top = bounds.y;
  start_rect_.right = bounds.x + bounds.width;
  start_rect_.bottom = bounds.y + bounds.height;

  CreateBrowserWindow(url);

  initialized_ = true;

  // Create the native root window on the main thread.
  if (CURRENTLY_ON_MAIN_THREAD()) {
    CreateRootWindow(settings);
  } else {
    MAIN_POST_CLOSURE(
        base::Bind(&RootWindowWin::CreateRootWindow, this, settings));
  }
}

void RootWindowWin::InitAsPopup(RootWindow::Delegate* delegate,
                                bool with_controls,
                                bool with_osr,
                                const CefPopupFeatures& popupFeatures,
                                CefWindowInfo& windowInfo,
                                CefRefPtr<CefClient>& client,
                                CefBrowserSettings& settings) {
  CEF_REQUIRE_UI_THREAD();

  DCHECK(delegate);
  DCHECK(!initialized_);

  delegate_ = delegate;
  with_controls_ = with_controls;
  with_osr_ = with_osr;
  is_popup_ = true;

  if (popupFeatures.xSet)
    start_rect_.left = popupFeatures.x;
  if (popupFeatures.ySet)
    start_rect_.top = popupFeatures.y;
  if (popupFeatures.widthSet)
    start_rect_.right = start_rect_.left + popupFeatures.width;
  if (popupFeatures.heightSet)
    start_rect_.bottom = start_rect_.top + popupFeatures.height;

  CreateBrowserWindow(std::string());

  initialized_ = true;

  // The new popup is initially parented to a temporary window. The native root
  // window will be created after the browser is created and the popup window
  // will be re-parented to it at that time.
  browser_window_->GetPopupConfig(TempWindow::GetWindowHandle(), windowInfo,
                                  client, settings);
}

void RootWindowWin::Show(ShowMode mode) {
  REQUIRE_MAIN_THREAD();

  if (!hwnd_)
    return;

  int nCmdShow = SW_SHOWNORMAL;
  switch (mode) {
    case ShowMinimized:
      nCmdShow = SW_SHOWMINIMIZED;
      break;
    case ShowMaximized:
      nCmdShow = SW_SHOWMAXIMIZED;
      break;
    default:
      break;
  }

  ShowWindow(hwnd_, nCmdShow);
  UpdateWindow(hwnd_);
}

void RootWindowWin::Hide() {
  REQUIRE_MAIN_THREAD();

  if (hwnd_)
    ShowWindow(hwnd_, SW_HIDE);
}

void RootWindowWin::SetBounds(int x, int y, size_t width, size_t height) {
  REQUIRE_MAIN_THREAD();

  if (hwnd_) {
    SetWindowPos(hwnd_, NULL, x, y, static_cast<int>(width),
                 static_cast<int>(height), SWP_NOZORDER);
  }
}

void RootWindowWin::Close(bool force) {
  REQUIRE_MAIN_THREAD();
 
  COPYDATASTRUCT MyCDS;
  CEFHWMSG rec;
  swprintf(rec.data, 255, L"%s", MainContext::Get()->GetAppName().ToWString().c_str());
  MyCDS.dwData = WM_APPCLOSE;
  MyCDS.cbData = sizeof(rec);
  MyCDS.lpData = &rec;
  SendMessage(MainContext::Get()->GetCallerHwnd(),
	  WM_COPYDATA,
	  NULL,
	  (LPARAM)(LPVOID)&MyCDS);

  if (MainContext::Get()->IsCinemaApp() && aftersome_play_hwnd_ != 0) {
	  SendMessage(aftersome_play_hwnd_,
		  WM_CEFCLOSE,
		  NULL,
		  NULL);
  }

  if (LOGDEBUG) _cprintf("send close message to %d\n", MainContext::Get()->GetCallerHwnd());

  if (hwnd_) {
    if (force)
      DestroyWindow(hwnd_);
    else
      PostMessage(hwnd_, WM_CLOSE, 0, 0);
  }
}

void RootWindowWin::SetDeviceScaleFactor(float device_scale_factor) {
  REQUIRE_MAIN_THREAD();

  if (browser_window_)
    browser_window_->SetDeviceScaleFactor(device_scale_factor);
}

float RootWindowWin::GetDeviceScaleFactor() const {
  REQUIRE_MAIN_THREAD();

  if (browser_window_)
    return browser_window_->GetDeviceScaleFactor();
  return client::GetDeviceScaleFactor();
}

CefRefPtr<CefBrowser> RootWindowWin::GetBrowser() const {
  REQUIRE_MAIN_THREAD();

  if (browser_window_)
    return browser_window_->GetBrowser();
  return NULL;
}

ClientWindowHandle RootWindowWin::GetWindowHandle() const {
  REQUIRE_MAIN_THREAD();
  return hwnd_;
}

void RootWindowWin::CreateBrowserWindow(const std::string& startup_url) {
  if (with_osr_) {
    OsrRenderer::Settings settings = {};
    MainContext::Get()->PopulateOsrSettings(&settings);
    browser_window_.reset(new BrowserWindowOsrWin(this, startup_url, settings));
  } else {
    browser_window_.reset(new BrowserWindowStdWin(this, startup_url));
  }
}

static bool CreateMoveWin() {
	if (g_movehWnd == NULL) {
		RECT originrect;
		GetWindowRect(g_roothwnd, &originrect);
		_cprintf("create movable window\n");
		swprintf_s(g_classname, L"movable%d", g_wcount);
		g_wcount++;
		g_movewndclass.lpfnWndProc = MoveWindowProc;
		g_movewndclass.cbClsExtra = 0;
		g_movewndclass.cbWndExtra = 0;
		g_movewndclass.style = CS_HREDRAW | CS_VREDRAW;
		g_movewndclass.lpszClassName = g_classname;
		g_movewndclass.hInstance = 0;
		g_movewndclass.hCursor = g_cursor;
		g_movewndclass.hIcon = 0;
		g_movewndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		g_movewndclass.lpszMenuName = 0;
		//注册窗口类
		if (RegisterClass(&g_movewndclass) == 0)
		{
			MessageBox(0, _T("注册窗口类失败"), _T("moveable"), MB_OK);
			return false;
		}
		DWORD  dwStyle = WS_THICKFRAME | WS_CLIPCHILDREN;
		g_movehWnd = CreateWindow(g_classname, _T("窗体移动框"),
			dwStyle, originrect.left, originrect.top, originrect.right - originrect.left, originrect.bottom - originrect.top, 0, 0, 0, 0);

		SetWindowLong(g_movehWnd, GWL_STYLE, WS_OVERLAPPED);
		ShowWindow(g_movehWnd, SW_SHOW);
	}
	else {
		if (!IsWindowVisible(g_movehWnd)) {
			ShowWindow(g_movehWnd, SW_SHOW);
		}
	}
	return true;
}
 
  
LRESULT CALLBACK MyMouseHook(int nCode, WPARAM wp, LPARAM lp)
{
	//MOUSEHOOKSTRUCT *pmh = (MOUSEHOOKSTRUCT *)lp;
	if (nCode >= 0) {
		if (wp == WM_LBUTTONDOWN ) { 
			//_cprintf("hook:: WM_LBUTTONDOWN  \n"  );
			GetWindowRect(g_roothwnd, &g_clientrect);
			POINT curpoint;
			GetCursorPos(&curpoint);
			 
			if (curpoint.x >= g_clientrect.left && curpoint.x <= g_clientrect.right
				&& curpoint.y >= g_clientrect.top + 50  && curpoint.y  <= g_clientrect.bottom) {
				if (g_reach) {
					_cprintf("\nhook:: WM_LBUTTONDOWN\n");
					g_resize = true;
					GetCursorPos(&g_startpoint);
				}
			}
		}
		else if (wp == WM_LBUTTONUP) {
			 
			//_cprintf("hook:: WM_LBUTTONUP  \n"  );
 
			if (g_resize) {
				g_resize = false;
				RECT r;
				if (g_movehWnd) {
					_cprintf(" destroy move window \n");
					GetWindowRect(g_movehWnd, &r);
					ShowWindow(g_movehWnd,  SW_HIDE);
					MoveWindow(g_roothwnd, r.left, r.top, r.right - r.left, r.bottom - r.top, TRUE);				 
				}		
				SetCursor(g_arrowcursor);
			}
			g_reach = false; 
		} else if (wp == WM_MOUSEMOVE) { 
			 
			if (!g_dragWindow) {
				if ( g_resize) {
					POINT curpoint;
					RECT originrect;
					GetWindowRect(g_roothwnd, &originrect);
					GetCursorPos(&curpoint);
					if (g_rightreach && g_bottomreach) {
						int w = originrect.right - originrect.left + (curpoint.x - g_startpoint.x);
						int h = originrect.bottom - originrect.top + (curpoint.y - g_startpoint.y);
						if (w < g_default_store_w)  w = g_default_store_w;
						if (h < g_default_store_h) h = g_default_store_h;
					 
							//_cprintf("resize it w = %d, h = %d\n", w, h);
							if (!CreateMoveWin()) return 0;
							//_cprintf("moving......\n");
							SetCursor(g_cursor);
							MoveWindow(g_movehWnd, originrect.left, originrect.top, w, h, TRUE);
 
					}
					/*
					else if (g_rightreach) { 
						int w = originrect.right - originrect.left + (curpoint.x - g_startpoint.x);
						int h = originrect.bottom - originrect.top;
						if (w < g_default_store_w) {
							//  less then min size, do nothing
						}
						else {
							//_cprintf("resize it w = %d, h = %d\n", w, h);
							if (!CreateMoveWin()) return 0;
							//_cprintf("moving......\n");
							SetCursor(g_cursor);
							MoveWindow(g_movehWnd, originrect.left, originrect.top, w, h, TRUE);
 
						}
					}
					else if (g_bottomreach) {
						int w = originrect.right - originrect.left  ;
						int h = originrect.bottom - originrect.top + (curpoint.y - g_startpoint.y);
						if (h < g_default_store_h) {
							//  less then min size, do nothing
						}
						else {
							//_cprintf("resize it w = %d, h = %d\n", w, h);
							if (!CreateMoveWin()) return 0;
							//_cprintf("moving......\n");
							SetCursor(g_cursor);
							MoveWindow(g_movehWnd, originrect.left, originrect.top, w, h, TRUE);
 
						}
					} */
					return 0;
				}
				else { 		
					 
					POINT curpoint;
					RECT originrect;
					GetWindowRect(g_roothwnd, &originrect);
					GetCursorPos(&curpoint);
					//_cprintf("mouse hook:: mouse move    %d  %d  %d  %d  \n", curpoint.x, curpoint.y, originrect.left, originrect.top);
					if (curpoint.x >= originrect.left && curpoint.x <= originrect.right && curpoint.y >= originrect.top + 60 && curpoint.y <= originrect.bottom) {
						g_leftreach = abs(originrect.left - curpoint.x) <= 20;
						g_rightreach = abs(originrect.right - curpoint.x) <= 20;
						g_bottomreach = abs(originrect.bottom - curpoint.y) <= 20;
						g_reach = g_leftreach | g_rightreach | g_bottomreach;
						// _cprintf("originrect.right=  %d   curpoint.x= %d  %d \n", originrect.right , curpoint.x, g_rightreach);
						if (g_leftreach) {
							//g_cursor = LoadCursor(NULL, IDC_SIZEWE);
							//SetCursor(g_cursor);
						}
						else if (g_rightreach && g_bottomreach) {
							g_isarrow = false;
							g_cursor = LoadCursor(NULL, IDC_SIZENWSE);
							//SetCursor(g_cursor);
						}
						else if (g_rightreach) {
							//g_isarrow = false;
							//g_cursor = g_wecursor;
							//SetCursor(g_cursor);
							//_cprintf("mouse hook:: right reach    %d   %d \n", originrect.right - curpoint.x, g_rightreach);
						} 
						else if (g_bottomreach) {
							//g_isarrow = false;
							//g_cursor = LoadCursor(NULL, IDC_SIZENS);
							//SetCursor(g_cursor);
						}
						else {
							//_cprintf("mouse hook:: set cursor to arrow\n");
							if (!g_isarrow) {
								SetCursor(g_arrowcursor);
								g_isarrow = true;
							}						 
						}
					}
 
				}
			}
		}
	}
	return CallNextHookEx(NULL, nCode, wp, lp);
	//return 0;
}


void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) {
  REQUIRE_MAIN_THREAD();
  DCHECK(!hwnd_);
  HINSTANCE hInstance = GetModuleHandle(NULL);

  // Load strings from the resource file.
  const std::wstring& window_title = L""; // GetResourceString(IDS_APP_TITLE);
  //const std::wstring& window_class = GetResourceString(IDC_CEFCLIENT);
  const std::wstring& window_class = MainContext::Get()->GetWinClassName();

  const cef_color_t background_color = MainContext::Get()->GetBackgroundColor();
  const HBRUSH background_brush = CreateSolidBrush(
      RGB(CefColorGetR(background_color), CefColorGetG(background_color),
          CefColorGetB(background_color)));

  // Register the window class.
  RegisterRootClass(hInstance, window_class, background_brush);

  // Register the message used with the find dialog.
  find_message_id_ = RegisterWindowMessage(FINDMSGSTRING);
  CHECK(find_message_id_);

 
  DWORD  dwStyle = WS_THICKFRAME | WS_CLIPCHILDREN;// | WS_SYSMENU | WS_MINIMIZE;  // fxf version
  if (FXFTEST)
	  dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;  // this is origin
  else
      dwStyle =  WS_THICKFRAME | WS_CLIPCHILDREN ; // | WS_MINIMIZE | WS_MAXIMIZE| WS_MINIMIZEBOX | WS_MAXIMIZEBOX;  // fxf version

  if ( (MainContext::Get()->IsLoginApp()  && is_popup_)  ) {
	  if (LOGDEBUG)  _cprintf("popup login window , has SYSMENU \n");
	  dwStyle |= WS_SYSMENU;
  }

  int x, y, width, height;
  /*
  if (is_popup_) {
	  CefRect  rc = MainContext::Get()->GetBound();
	  if (LOGDEBUG)  _cprintf("RootWindowWin::CreateRootWindow  is popup, redefine rect by param\n");
	  if (!rc.IsEmpty()) {
		  start_rect_.top = rc.y;
		  start_rect_.left = rc.x;
		  start_rect_.bottom = rc.y + rc.height;
		  start_rect_.right = rc.x + rc.width;
	  }
  }
  */
  if (::IsRectEmpty(&start_rect_)) {
    // Use the default window position/size.
	  if (LOGDEBUG)  _cprintf("RootWindowWin::CreateRootWindow  start_rect is empty, user default value\n");
	  start_rect_.top = y = 50;
	  start_rect_.left = x = 50;
	  start_rect_.bottom = 800;
	  start_rect_.right =1000;
	  width = start_rect_.right - start_rect_.left;
	  height = start_rect_.bottom - start_rect_.top;
    //x = y = width = height = CW_USEDEFAULT;

  } else {
    // Adjust the window size to account for window frame and controls.
    RECT window_rect = start_rect_; 
    x = start_rect_.left;
    y = start_rect_.top;
    width = window_rect.right - window_rect.left;
    height = window_rect.bottom - window_rect.top;
  }

  if (LOGDEBUG) _cprintf("root windoow  posotion and size %d  %d   %d   %d\n", x, y, width, height);
  //fxf begin
  RECT desktop;
  if (MainContext::Get()->IsFullScreen()) {
	  const HWND hDesktop = GetDesktopWindow();
	  GetWindowRect(hDesktop, &desktop);
	  x = 0;
	  y = 0;
	  height = desktop.bottom - desktop.top;
	  width = desktop.right - desktop.left;
  } else if (MainContext::Get()->IsLoginApp() ) {
	  const HWND hDesktop = GetDesktopWindow();
	  GetWindowRect(hDesktop, &desktop);
	  if (is_popup_) {
		  width = g_qq_width;
		  height = g_qq_height;
		  x = ((desktop.right - desktop.left) - width )/ 2 + g_offset;
		  y = ((desktop.bottom - desktop.top) - height) / 2 + g_offset;
	  }
	  else {
		  width = g_upup_login_width;
		  height = g_upup_login_height;
		  x = ((desktop.right - desktop.left) - width) / 2;
		  y = ((desktop.bottom - desktop.top) - height) / 2;
	  }
	  if (LOGDEBUG) _cprintf("login window %d %d %d %d   x = %d  y = %d \n", desktop.left, desktop.top, desktop.right, desktop.bottom, x, y);
  }
  else if (MainContext::Get()->IsUserDetailApp()) {
	  const HWND hDesktop = GetDesktopWindow();
	  GetWindowRect(hDesktop, &desktop);
	  //width = default_userwin_with;
	  //height = default_userwin_height;
	  width = start_rect_.right - start_rect_.left;
	  height = start_rect_.bottom - start_rect_.top;
	  x = ((desktop.right - desktop.left) - width) / 2;
	  y = ((desktop.bottom - desktop.top) - height) / 2;
  }
  else if (MainContext::Get()->IsGalleryApp()  || MainContext::Get()->IsCinemaApp()) {
	  if (is_popup_) {
		  if (MainContext::Get()->GetPopupType() == MainContext::PopupType::popcomment) {
			  HWND h = MainContext::Get()->GetPopupParentWindow();
			  RECT rect;
			  GetWindowRect(h, &rect);
			  x = rect.right;
			  y = rect.top;
			  width = 300;
			  height = rect.bottom - rect.top;
		  }
	  }
	  else {
		  const HWND hDesktop = GetDesktopWindow();
		  GetWindowRect(hDesktop, &desktop);
		  width = g_default_store_w;
		  height = g_default_store_h;
		  x = ((desktop.right - desktop.left) - width) / 2;
		  y = ((desktop.bottom - desktop.top) - height) / 2;
	  }
  }
  else if (MainContext::Get()->IsUserGuideApp()) {
	  const HWND hDesktop = GetDesktopWindow();
	  GetWindowRect(hDesktop, &desktop);
	  width = g_guide_w;
	  height = g_guide_h;
	  x = ((desktop.right - desktop.left) - width) / 2;
	  y = ((desktop.bottom - desktop.top) - height) / 2;
  }

  float scale = client::GetDeviceScaleFactor();
  if(LOGDEBUG) _cprintf("x   %d  y  %d  w  %d   h  %d, scale  %0.2f \n", x, y, width, height, scale);
  if (!MainContext::Get()->IsAfterSomeApp()
	  && !MainContext::Get()->IsCaptureApp() 
	  && !MainContext::Get()->IsWebplayerApp()
	  && !MainContext::Get()->IsFullScreen()
	  && scale > 1) {
	  int  wex = width * (scale - 1);
	  int hex = height * (scale - 1);
	  if (x != 0)  x -=  wex / 2;
	  if (y != 0) y -= hex / 2;
	  width += wex;
	  height += hex;
	  if (LOGDEBUG) _cprintf("after scale:: x   %d  y  %d  w  %d   h  %d, scale  %0.2f \n", x, y, width, height, scale);
  }
  client_rect_.left = x;
  client_rect_.top = y;
  client_rect_.right = x + width;
  client_rect_.bottom = y + height;
  // Create the main window initially hidden.
  hwnd_ = CreateWindow(window_class.c_str(), window_title.c_str(), dwStyle, x,
                       y, width, height, NULL, NULL, hInstance, NULL);
  g_roothwnd = hwnd_;
  CHECK(hwnd_);
  if (LOGDEBUG)  _cprintf("root window handler is %d -------------\n", hwnd_);
  DragAcceptFiles( hwnd_,true);

  if (true) {
	  
	  SetMenu(hwnd_, NULL);

	  if (MainContext::Get()->IsLoginApp()) {
 
		  if (LOGDEBUG)  _cprintf("set topmost\n");
		  SetWindowPos(hwnd_, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);

		  if ( is_popup_) {
			  if (LOGDEBUG)   _cprintf("set %d 's owner %d as self login\n", hwnd_, MainContext::Get()->GetPopupParentWindow());
			  SetWindowLong(hwnd_, GWL_HWNDPARENT, (long)MainContext::Get()->GetPopupParentWindow());
		  }
		  else {
			  if (LOGDEBUG)  _cprintf("set window transparent value 200 and always on top\n");
			  LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE);
			  style |= WS_EX_LAYERED;
			  SetWindowLong(hwnd_, GWL_EXSTYLE, style);
			  SetLayeredWindowAttributes(hwnd_, RGB(0, 0, 0), g_alpha_value, LWA_ALPHA);
			  // if set with LVW_COLORKEY, this window will miss mouse event. mouse event will transfer to the behind.
			  //SetLayeredWindowAttributes(hwnd_, RGB(0, 0, 0), g_alpha_value, ULW_ALPHA);
		  }			   
	  }
	  else if (MainContext::Get()->IsGalleryApp() || MainContext::Get()->IsCinemaApp()) {
		  LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE);
		  style |= WS_EX_LAYERED;
		  SetWindowLong(hwnd_, GWL_EXSTYLE, style);
		  SetLayeredWindowAttributes(hwnd_, RGB(0, 0, 0), 240, LWA_ALPHA); 
	  }
	  else if (MainContext::Get()->IsUserDetailApp()) {
		  SetWindowPos(hwnd_, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
	  }

	  if (!FXFTEST) {
		  _cprintf("remove title bar\n");
		  if (MainContext::Get()->IsLoginApp() && is_popup_) {
			  // has title bar for google popup loign
		  }
		  else { 
			  SetWindowLong(hwnd_, GWL_STYLE, WS_OVERLAPPED | WS_MINIMIZEBOX);  // set window no titlebar
			  //long flags = GetWindowLong(hwnd_, GWL_EXSTYLE);
			  //flags |= WS_EX_TOOLWINDOW;  // this will let window can not enter to taskbar
			  //SetWindowLong(hwnd_, GWL_EXSTYLE, flags);		 
		  }
	  }

	  if (MainContext::Get()->IsWebplayerApp()) {
		  //long flags = GetWindowLong(hwnd_, GWL_EXSTYLE);
		  //flags |= WS_EX_TOOLWINDOW;  // this will let window can not enter to taskbar
		  //SetWindowLong(hwnd_, GWL_EXSTYLE, flags);
	  }
	  
	  HWND callerhwnd = MainContext::Get()->GetCallerHwnd();

	  if (MainContext::Get()->IsAfterSomeApp()) {
		  if (LOGDEBUG)  _cprintf("set parent when create rootwindow.\n");
		  SetParent(hwnd_, callerhwnd); // fxf test
		  has_set_parent_ = true;
	  }
	  else {
		  has_set_parent_ = false;
	  }

	  if (!is_popup_) {
		  MainContext::Get()->SavePopupParentWindow(hwnd_);
		  MainContext::Get()->SaveRootHandler(hwnd_);
	  }

	  if (MainContext::Get()->IsLoginApp() && is_popup_) {
		  MainContext::Get()->SaveLoginPopupHandler(hwnd_);
	  }

	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG MyRec;
	  MyRec.value = (DWORD)hwnd_;
	  CefString name = MainContext::Get()->GetAppName();
	  swprintf(MyRec.data, 255, name.ToWString().c_str());

	  MyCDS.dwData = WM_DMYHWND;
	  MyCDS.cbData = sizeof(MyRec);
	  MyCDS.lpData = &MyRec;

	  if ( MainContext::Get()->IsNewTabApp()  || MainContext::Get()->IsAfterSomeApp() ) {
		  tabid_ = MainContext::Get()->GetTabId();  // if popup, This is from last root window receive open command and save tabid; 
													// if not popup, this is from --tabid param. anywhere, save it as member value.
		  if (  is_popup_ &&  tabid_ == 0) {  // this popup is from js open, not from command open.  
			  SYSTEMTIME SystemTime;
			  GetSystemTime(&SystemTime);
			  std::stringstream  s;
			  s << SystemTime.wHour << SystemTime.wMinute << SystemTime.wSecond << SystemTime.wMilliseconds;
			  tabid_ = std::atoi(  s.str().c_str() );
			  if (LOGDEBUG) _cprintf("create popup tabid  =  %d", tabid_);
		  }
		  MainContext::Get()->SaveTabId(0); // reset after member value assigned
		  SendMessage(callerhwnd,
			  WM_COPYDATA,
			  (WPARAM)tabid_,
			  (LPARAM)(LPVOID)&MyCDS);
		  if (LOGDEBUG) _cprintf("send DMYHWND messge to caller %d tabid = %d\n", callerhwnd, tabid_);
	  }
	  else {
		  if (is_popup_ && MainContext::Get()->IsLoginApp()) {
			  _cprintf("Here is google login, do not send my hwnd to caller\n");
		  }
		  else {
			  if (LOGDEBUG) _cwprintf(L" %d send message to caller %d, [%s]  \n", hwnd_, callerhwnd, MyRec.data);
			  SendMessage(callerhwnd,
				  WM_COPYDATA,
				  NULL,
				  (LPARAM)(LPVOID)&MyCDS);
		  }
	  }	   
  }

  // Associate |this| with the main window.
  SetUserDataPtr(hwnd_, this);

  RECT rect;
  GetClientRect(hwnd_, &rect);
  rect.right = start_rect_.right - start_rect_.left + rect.left;
  rect.bottom = start_rect_.bottom - start_rect_.top + rect.top;
 
  if (LOGDEBUG) _cprintf("browser windoow   %d  %d   %d   %d\n", rect.top, rect.left, rect.bottom, rect.right);

  if (LOGDEBUG) {
	  float dpi = client::GetDeviceScaleFactor(); 
	 int w = LogicalToDevice(300, client::GetDeviceScaleFactor());
	 _cprintf("DeviceScale %f,  %d\n", dpi, w);
  }

  if (FXFTEST) {
	  with_controls_ = true;  // fxf test
  }
  else {
	  with_controls_ = false;  // fxf test
  }
  if (with_controls_) {
    // Create the child controls.
    int x_offset = 0;

    const int button_width = GetButtonWidth();
    const int urlbar_height = GetURLBarHeight();
    const int font_height = LogicalToDevice(14, client::GetDeviceScaleFactor());

    // Create a scaled font.
    font_ =
        ::CreateFont(-font_height, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
                     DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
                     DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");

    back_hwnd_ = CreateWindow(
        L"BUTTON", L"Back", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
        x_offset, 0, button_width, urlbar_height, hwnd_,
        reinterpret_cast<HMENU>(IDC_NAV_BACK), hInstance, 0);
    CHECK(back_hwnd_);
    SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
    x_offset += button_width;

    forward_hwnd_ =
        CreateWindow(L"BUTTON", L"Forward",
                     WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
                     x_offset, 0, button_width, urlbar_height, hwnd_,
                     reinterpret_cast<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
    CHECK(forward_hwnd_);
    SendMessage(forward_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
                TRUE);
    x_offset += button_width;

    reload_hwnd_ =
        CreateWindow(L"BUTTON", L"Reload",
                     WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
                     x_offset, 0, button_width, urlbar_height, hwnd_,
                     reinterpret_cast<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
    CHECK(reload_hwnd_);
    SendMessage(reload_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
                TRUE);
    x_offset += button_width;

    stop_hwnd_ = CreateWindow(
        L"BUTTON", L"Stop", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
        x_offset, 0, button_width, urlbar_height, hwnd_,
        reinterpret_cast<HMENU>(IDC_NAV_STOP), hInstance, 0);
    CHECK(stop_hwnd_);
    SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
    x_offset += button_width;

    edit_hwnd_ = CreateWindow(L"EDIT", 0,
                              WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
                                  ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_DISABLED,
                              x_offset, 0, rect.right - button_width * 4,
                              urlbar_height, hwnd_, 0, hInstance, 0);
    SendMessage(edit_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
    CHECK(edit_hwnd_);

    edit_wndproc_old_ = SetWndProcPtr(edit_hwnd_, EditWndProc);

    // Associate |this| with the edit window.
    SetUserDataPtr(edit_hwnd_, this);

    rect.top += urlbar_height;

    if (!with_osr_) {
      // Remove the menu items that are only used with OSR.
      HMENU hMenu = ::GetMenu(hwnd_);
      if (hMenu) {
        HMENU hTestMenu = ::GetSubMenu(hMenu, 2);
        if (hTestMenu) {
          ::RemoveMenu(hTestMenu, ID_TESTS_OSR_FPS, MF_BYCOMMAND);
          ::RemoveMenu(hTestMenu, ID_TESTS_OSR_DSF, MF_BYCOMMAND);
        }
      }
    }
  } else {
    // No controls so also remove the default menu.
    ::SetMenu(hwnd_, NULL);
  }

  if (MainContext::Get()->IsFullScreen()) {
	  rect = desktop;  // fxf add test
  }

  if (!is_popup_) {
    // Create the browser window.
    CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
                     rect.bottom - rect.top);
    browser_window_->CreateBrowser(hwnd_, cef_rect, settings,
                                   delegate_->GetRequestContext(this));
  } else {
    // With popups we already have a browser window. Parent the browser window
    // to the root window and show it in the correct location.
    browser_window_->ShowPopup(hwnd_, rect.left, rect.top,
                               rect.right - rect.left, rect.bottom - rect.top);
 
		if (LOGDEBUG) _cprintf("pupup window   left: %d  top:  %d  width: %d,  height:  %d\n", rect.left, rect.top,
			rect.right - rect.left, rect.bottom - rect.top);

  }
   
  if (MainContext::Get()->IsNewTabApp() ||   MainContext::Get()->IsAfterSomeApp()) {
	  // do not show it at this moment, will be shown browser load ended
	  _cprintf("do not show it till load end\n");
	  is_showing_ = false;
  } else {
	  if (LOGDEBUG)  is_showing_ = true;
	  Show(ShowNormal); 
	  if (LOGDEBUG) 	  _cprintf("show it when create root window.\n");
  }


  if (MainContext::Get()->IsGalleryApp() || MainContext::Get()->IsCinemaApp()) {
	  SetWindowsHookEx(WH_MOUSE_LL, MyMouseHook, NULL, 0);
  }

  //if ( false)
  //{
	 // NOTIFYICONDATA nidApp;
	 // ZeroMemory(&nidApp, sizeof(NOTIFYICONDATA));
	 // nidApp.cbSize = sizeof(NOTIFYICONDATA);
	 // nidApp.hWnd = (HWND)MainContext::Get()->GetRootHandler();
	 // nidApp.uID = IDI_CEFCLIENT;
	 // nidApp.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	 // nidApp.hIcon = LoadIcon(hInstance, (LPCTSTR)MAKEINTRESOURCE(IDI_CEFCLIENT));
	 // nidApp.uCallbackMessage = WM_USER_SHELLICON;
	 //  
	 // swprintf_s(nidApp.szTip,L"ceftray"); 
	 // Shell_NotifyIcon(NIM_ADD, &nidApp);
  //}
}

// static
void RootWindowWin::RegisterRootClass(HINSTANCE hInstance,
                                      const std::wstring& window_class,
                                      HBRUSH background_brush) {
  // Only register the class one time.
  static bool class_registered = false;
  if (class_registered)
    return;
  class_registered = true;

  WNDCLASSEX wcex;

  wcex.cbSize = sizeof(WNDCLASSEX);

  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = RootWndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = hInstance;
  if (MainContext::Get()->IsLoginApp()) {
	  wcex.hIcon = NULL;
  }
  else {
	  //HICON hIcon = static_cast<HICON>(LoadImage(hInstance,
		 // MAKEINTRESOURCE(IDI_ICON4),
		 // IMAGE_ICON,
		 // 48, 48,    // or whatever size icon you want to load
		 // LR_DEFAULTCOLOR));
	  wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CEFCLIENT));
  }
   
  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  g_cursor = LoadCursor(NULL, IDC_ARROW);
  g_arrowcursor = LoadCursor(NULL, IDC_ARROW);
  g_wecursor = LoadCursor(NULL, IDC_SIZEWE);
  wcex.hbrBackground = background_brush;
  wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CEFCLIENT);
  wcex.lpszClassName = window_class.c_str();
  if (MainContext::Get()->IsLoginApp()) {
	  wcex.hIconSm = NULL;
  }
  else {
	  wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  }
   
  RegisterClassEx(&wcex);
}

// static
LRESULT CALLBACK RootWindowWin::EditWndProc(HWND hWnd,
                                            UINT message,
                                            WPARAM wParam,
                                            LPARAM lParam) {
  REQUIRE_MAIN_THREAD();

  RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
  DCHECK(self);
  DCHECK(hWnd == self->edit_hwnd_);

  switch (message) {
    case WM_CHAR:
      if (wParam == VK_RETURN) {
        // When the user hits the enter key load the URL.
        CefRefPtr<CefBrowser> browser = self->GetBrowser();
        if (browser) {
          wchar_t strPtr[MAX_URL_LENGTH + 1] = {0};
          *((LPWORD)strPtr) = MAX_URL_LENGTH;
          LRESULT strLen = SendMessage(hWnd, EM_GETLINE, 0, (LPARAM)strPtr);
          if (strLen > 0) {
            strPtr[strLen] = 0;
            browser->GetMainFrame()->LoadURL(strPtr);
          }
        }
        return 0;
      }
      break;
    case WM_NCDESTROY:
      // Clear the reference to |self|.
      SetUserDataPtr(hWnd, NULL);
      self->edit_hwnd_ = NULL;
      break;
  }

  return CallWindowProc(self->edit_wndproc_old_, hWnd, message, wParam, lParam);
}

// static
LRESULT CALLBACK RootWindowWin::FindWndProc(HWND hWnd,
                                            UINT message,
                                            WPARAM wParam,
                                            LPARAM lParam) {
  REQUIRE_MAIN_THREAD();

  RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
  DCHECK(self);
  DCHECK(hWnd == self->find_hwnd_);

  switch (message) {
    case WM_ACTIVATE:
      // Set this dialog as current when activated.
      MainMessageLoop::Get()->SetCurrentModelessDialog(wParam == 0 ? NULL
                                                                   : hWnd);
      return FALSE;
    case WM_NCDESTROY:
      // Clear the reference to |self|.
      SetUserDataPtr(hWnd, NULL);
      self->find_hwnd_ = NULL;
      break;
  }

  return CallWindowProc(self->find_wndproc_old_, hWnd, message, wParam, lParam);
}


BOOL CALLBACK RootWindowWin::MyPaintEnumProc(
	HMONITOR hMonitor,  // handle to display monitor
	HDC hdc1,     // handle to monitor DC
	LPRECT lprcMonitor, // monitor intersection rectangle
	LPARAM data       // data
)
{
	RECT rc = *lprcMonitor;
	// you have the rect which has coordinates of the monitor
	if (LOGDEBUG) _cprintf("monitor  %d  %d %d%d  \n", rc.left, rc.top, rc.right, rc.bottom);
	// Draw here now
	return 1;
}

// static
LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd,
                                            UINT message,
                                            WPARAM wParam,
                                            LPARAM lParam) {
  REQUIRE_MAIN_THREAD();

  RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
  if (!self)
    return DefWindowProc(hWnd, message, wParam, lParam);
  DCHECK(hWnd == self->hwnd_);

  if (message == self->find_message_id_) {
    // Message targeting the find dialog.
    LPFINDREPLACE lpfr = reinterpret_cast<LPFINDREPLACE>(lParam);
    CHECK(lpfr == &self->find_state_);
    self->OnFindEvent();
    return 0;
  }

  //_cprintf("command   %x\n", message);
  // Callback for the main window
  switch (message) {
    case WM_COMMAND:
      if (self->OnCommand(LOWORD(wParam)))
        return 0;
      break;

    case WM_GETOBJECT: {
      // Only the lower 32 bits of lParam are valid when checking the object id
      // because it sometimes gets sign-extended incorrectly (but not always).
      DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(lParam));

      // Accessibility readers will send an OBJID_CLIENT message.
      if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) {
        if (self->GetBrowser() && self->GetBrowser()->GetHost())
          self->GetBrowser()->GetHost()->SetAccessibilityState(STATE_ENABLED);
      }
    } break;

 
    case WM_PAINT:
      self->OnPaint();
      return 0;

    case WM_SETFOCUS:
      self->OnFocus();
      return 0;

	case WM_USER_SHELLICON:
		_cprintf("WM_USER_SHELLICON\n");
		break;

    case WM_SIZE:
	{
		int width = LOWORD(lParam);
		int height = HIWORD(lParam); 
		if (LOGDEBUG) _cprintf("WM_SIZE-------------------- %d   w=%d  h=%d\n", wParam, width, height);
		self->OnSize(wParam == SIZE_MINIMIZED);
	}
      break;

	case WM_SIZING:
	{
		RECT* rect = (RECT*)lParam;
		if (rect->right - rect->left < 500 ||
			rect->bottom - rect->top < 500)
		{
			// 右压
			rect->left = g_clientrect.left;
			rect->right = g_clientrect.left + 500;
			rect->top = g_clientrect.top;
			rect->bottom = g_clientrect.top + 500;
		}
	}
	break;

	 
    case WM_MOVING:
    case WM_MOVE:
		self->OnMove();
      return 0;

	case WM_NCLBUTTONDOWN:
		if (wParam == HTCAPTION && MainContext::Get()->IsLoginApp()) {
			return 0;
		}
		break;
    case WM_ERASEBKGND:
      if (self->OnEraseBkgnd())
        break;
      // Don't erase the background.
      return 0;

    case WM_ENTERMENULOOP:
      if (!wParam) {
        // Entering the menu loop for the application menu.
        CefSetOSModalLoop(true);
      }
      break;

    case WM_EXITMENULOOP:
      if (!wParam) {
        // Exiting the menu loop for the application menu.
        CefSetOSModalLoop(false);
      }
      break;

	case WM_TITLEBLD:
	{
		if (LOGDEBUG ) _cprintf("WM_TITLEBLD\n");
		g_dragWindow = true;
		SetCapture(hWnd);
		GetWindowRect(hWnd, &g_clientrect);
		//save current cursor coordinate
		GetCursorPos(&g_startpoint);
		ScreenToClient(hWnd, &g_startpoint);
	}
		break;

	case WM_LBUTTONDOWN:
		if (LOGDEBUG)  _cprintf("WM_LBUTTONDOWN ----------");
	break;
 
	case WM_MOUSEMOVE:
		GetCursorPos(&g_nowpoint);
		//_cprintf("mouse pos  %d   %d\n", g_nowpoint.x, g_nowpoint.y);
		if (g_dragWindow)
		{
			CreateMoveWin();
			if (wParam == MK_LBUTTON)
			{
				int x = g_nowpoint.x - g_startpoint.x;
				int y = g_nowpoint.y - g_startpoint.y;
				if (abs(x) > 5 || abs(y) > 5) {
					MoveWindow(g_movehWnd, g_nowpoint.x - g_startpoint.x, g_nowpoint.y - g_startpoint.y,
						g_clientrect.right - g_clientrect.left, g_clientrect.bottom - g_clientrect.top,
						TRUE);
				}
			}
		}
		 
		break;

	case WM_TITLEBLU:
	case WM_LBUTTONUP:
		_cprintf("WM_LBUTTONUP %d\n");
		if ( g_dragWindow) {
			ReleaseCapture();
			POINT newpoint;
			GetCursorPos(&newpoint); 
			ShowWindow(g_movehWnd, SW_HIDE);
			g_dragWindow = false;
			MoveWindow(hWnd, newpoint.x  - g_startpoint.x, newpoint.y - g_startpoint.y,
				g_clientrect.right - g_clientrect.left, g_clientrect.bottom - g_clientrect.top,
				TRUE);
			_cprintf("hide  movable window and move real window\n");
		}
		break;

    case WM_CLOSE:
	  if (LOGDEBUG) _cprintf("WM_CLOSE  %d\n", self->hwnd_);

	  self->Hide();
	  if (self->OnClose())  
		  return 0;  // Cancel the close.
	  if (LOGDEBUG) _cprintf("WM_CLOSE  closed already\n");
	  break;

	case WM_COPYDATA:  //WM_DLOADURL:
		//if (LOGDEBUG)  _cprintf("cef root window receive message\n");
		if (lParam != NULL) {
			PCOPYDATASTRUCT pcds = (PCOPYDATASTRUCT)lParam;
			//if (LOGDEBUG)  _cwprintf(L"root window receive    %d --->\n", pcds->dwData);
			CEFHWMSG *ds = (CEFHWMSG *)pcds->lpData; 
			if (pcds->dwData == WM_DLOADURL) { 
				CefString  url;
				url.FromWString(ds->data);
				self->Show(ShowMode::ShowNormal);
				self->GetBrowser()->GetMainFrame()->LoadURL(ds->data);
				_cwprintf(L"load url is %s \n", ds->data );
			}
			/*
			else if (pcds->dwData == WM_OPENLOGIN) {
				if (LOGDEBUG)  _cprintf("popup windown to login  %d\n", ds->data);
				MainContext::Get()->SavePopupType(MainContext::PopupType::poplogin);
				MainContext::Get()->SavePopupParentWindow(self->hwnd_);

				std::wstring  url;
				url.append(L"window.open('");
				url.append(ds->data);
				url.append(L"');");
				CefString csurl;
				csurl.FromWString(url);

				self->GetBrowser()->GetMainFrame()->ExecuteJavaScript(
					csurl, "about:blank", 0);
			} */
			else if (pcds->dwData == WM_DHIDE) {
				self->is_showing_ = false;
				self->GetBrowser()->GetMainFrame()->LoadURL("about:blank");
				self->Hide();				 
				if (LOGDEBUG) _cprintf("hide it when WM_DHIDE  %d\n", self->tabid_);
				//MainContext::Get()->SaveShowStatus(false);
			} else if (pcds->dwData == WM_DSHOW) {				 
				if (!self->is_showing_) {
					self->is_showing_ = true;
					if (!self->has_set_parent_) {
						SetParent(self->hwnd_, MainContext::Get()->GetCallerHwnd());
					}
					if (LOGDEBUG) _cprintf("show it when WM_DSHOW  %d\n", self->tabid_);
					self->Show(ShowMode::ShowNormal);
					if (MainContext::Get()->IsCommentApp()) {
						self->GetBrowser()->Reload();
					}
				}			 
			}
			else if (pcds->dwData == WM_DBACK) {
				self->GetBrowser()->GoBack();
			} else if (pcds->dwData == WM_DFORWARD) {
				self->GetBrowser()->GoForward();
 
			} else if (pcds->dwData == WM_DRELOAD) {
				self->GetBrowser()->Reload();
			}
			else if (pcds->dwData == WM_DRESIZE) {
				RECT  r;
				GetClientRect(MainContext::Get()->GetCallerHwnd(), &r);
				int mergin_top = 0;
				if (wParam != NULL) {
					mergin_top = (int)wParam;
				}
				CefRect rect(0, mergin_top, r.right - r.left, r.bottom - mergin_top);
				MainContext::Get()->SaveBoundRect(rect);
				if (LOGDEBUG) _cprintf("WM_DRESIZE\n");
				SetWindowPos(self->hwnd_, NULL, 0,  mergin_top, r.right- r.left, r.bottom -mergin_top, SWP_NOZORDER);
			}
			else if (pcds->dwData == WM_DLOGOUT) {
				UserManager::Get()->Logout(); 
				self->GetBrowser()->GetMainFrame()->ExecuteJavaScript(
					"logout();", "about:blank", 0);
				 
				self->GetBrowser()->Reload();
				     
				if (LOGDEBUG) _cprintf("logout , clear token reload........\n");
			}
			else if (pcds->dwData == WM_DMYHWND) { // frome aftersomeplay application
				if (LOGDEBUG) _cprintf("receive aftersomeplay handler %d........\n", ds->value);
				self->browser_window_->GetClientHandler()->SetAftersomePlayHandler(ds->value);
				self->aftersome_play_hwnd_ = (HWND)ds->value;
			}
			else if (pcds->dwData == WM_APPCLOSE) { // frome aftersomeplay application
				if (LOGDEBUG) _cprintf("receive WM_APPCLOSE ........\n") ;
				if (MainContext::Get()->IsCinemaApp()) {
					if (LOGDEBUG) _cprintf("set playhandler as 0........\n");
					self->browser_window_->GetClientHandler()->SetAftersomePlayHandler(0);
					self->aftersome_play_hwnd_ = 0;
					CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
					CefRefPtr<CefListValue> args = msg->GetArgumentList();
					args->SetInt(0, 39);
					args->SetString(1, "");

					self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
					if (LOGDEBUG) _cwprintf(L"Send dramacalljs  39 \n");
				}			 
			}
			else if (pcds->dwData == WM_STORESTOPPLAY) {
				_cprintf("receive WM_STORESTOPPLAY message   \n" ); 
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 40);
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 40 to web\n");
			}
			else if (pcds->dwData == WM_STORERESUMEPLAY) {
				_cprintf("receive WM_STORERESUMEPLAY message  \n" );
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 41);
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 41 to web\n");
			}
			else if (pcds->dwData == WM_SILENCE) {
				_cprintf("receiveWM_SILENCE message \n" );
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 42);
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 42 to web\n");
			}
			else if (pcds->dwData == WM_SOUND) {
				_cprintf("receive WM_SOUND message   \n" );
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 43);
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 43 to web\n");
			}
			else if (pcds->dwData == WM_VOLUME) {
				_cprintf("receive WM_VOLUME\n" );			 
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 44);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 44 to web\n");
			}
			else if (pcds->dwData == WM_PLAYMODEL) {
				if (LOGDEBUG) _cprintf("receive WM_PLAYMODEL \n" );
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 45);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 45 to web\n");
			}
			else if (pcds->dwData == WM_DETAILPAPERID) {
				if (LOGDEBUG) _cprintf("receive WM_DETAILPAPERID \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 48);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 48 to web\n");
			}
			else if (pcds->dwData == WM_STOREPLAYNEXT) {
				_cprintf("receive WM_STOREPLAYNEXT \n" );
		 
				self->browser_window_->GetClientHandler()->PlayNext();
			}
			else if (pcds->dwData == WM_STOREPLAYPREVIOUS) {
				_cprintf("receive WM_STOREPLAYPREVIOUS \n" );
	  
				self->browser_window_->GetClientHandler()->PlayPrevious();
			}
			else if (pcds->dwData == WM_GOTOBINDPAGE) {
				_cprintf("receive bind page message %s \n", ds->data);
				self->GetBrowser()->GetMainFrame()->LoadURL(ds->data);
			} else if (pcds->dwData == WM_GALLERYMSG) { 
				if (LOGDEBUG) _cprintf("receive WM_GALLERYMSG \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				int openmsg = ds->value;
				CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
				dict->SetString("newmsgnum", ds->data);
				if ( openmsg == 0)
				   dict->SetString("openmsg","0");
				else 
					dict->SetString("openmsg", "1");
				CefRefPtr<CefValue> pValue = CefValue::Create();
				pValue->SetDictionary(dict);
				CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

				args->SetInt(0, 49);
				args->SetString(1, jsonString);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 49 to web  %s\n", jsonString.ToString().c_str());
			}
			else if (pcds->dwData == WM_GALLERYVEFIRYMSG) {
				if (LOGDEBUG) _cprintf("receive WM_GALLERYVEFIRYMSG \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 50);
				char buf[32];
				sprintf_s(buf, "%d", ds->value);
				CefString s(buf);
				args->SetString(1, s);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 50 to web  %s\n", s.ToString().c_str());
			}
			else if (pcds->dwData == WM_AFTERSOMEMSG) {
				if (LOGDEBUG) _cprintf("receive WM_AFTERSOMEMSG \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				int openmsg = ds->value;
				CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
				dict->SetString("newmsgnum", ds->data);
				if (openmsg == 0)
					dict->SetString("openmsg", "0");
				else
					dict->SetString("openmsg", "1");
				CefRefPtr<CefValue> pValue = CefValue::Create();
				pValue->SetDictionary(dict);
				CefString jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);

				args->SetInt(0, 51);
				args->SetString(1, jsonString);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cprintf("Send 51 to web  %s\n", jsonString.ToString().c_str());
			}
			else if (pcds->dwData ==	WM_GAMESTART) {
				if (LOGDEBUG) _cprintf("receive WM_GAMESTART \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 52); 
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);

				CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args2 = msg2->GetArgumentList();
				args2->SetInt(0, 52);
				args2->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg2);
				if (LOGDEBUG) _cprintf("Send 52 to web  \n"); 
			}
			else if (pcds->dwData == WM_GAMEEXIT) {
				if (LOGDEBUG) _cprintf("receive WM_GAMEEXIT \n");
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 53);
				args->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);

				CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args2 = msg2->GetArgumentList();
				args2->SetInt(0, 53);
				args2->SetString(1, "");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg2);
				if (LOGDEBUG) _cprintf("Send 53 to web  \n");
			}
			//else if (pcds->dwData == WM_DLOGINTOKEN) { 
			//	CefString  url;
			//	url.FromWString(ds->data);
			//	if (LOGDEBUG) _cprintf("receive token  %s........\n", url.ToString().c_str());
			//	CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("calljs");
			//	CefRefPtr<CefListValue> args = msg->GetArgumentList();
			//	args->SetInt(0, 16);
			//	args->SetString(1, url);
			//	self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			//	//发送token到JS页面
			//}
			else if (pcds->dwData == WM_DOWNLOADPROGRESS) {
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 18);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			}
			else if (pcds->dwData == WM_SPEED) {
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 54);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);

				if (LOGDEBUG) _cwprintf(L"download speed  %s\n", ds->data);
			}
			else if (pcds->dwData == WM_DOWNLOADSTATE) {
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 22);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			}
			else if (pcds->dwData == WM_DOWNPREVIEWREADY) {
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 24);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);			 
				if (LOGDEBUG) {
					_cwprintf(L"Send 24 %s\n", ds->data);
					_cprintf("  WM_DOWNPREVIEWREADY  threadid  %d\n", GetCurrentThreadId());
				}
			}
			else if (pcds->dwData == WM_ADDEDTOLIST) { 
				_cprintf("  WM_ADDEDTOLIST  threadid  %d\n", GetCurrentThreadId());
				CefString themeno = ds->data;
				self->browser_window_->GetClientHandler()->AddFinishedPaperToList(themeno, false);				 
			}
			else if (pcds->dwData == WM_ADDEDTOLISTANDNOTIFY) {
				_cprintf("  WM_ADDEDTOLIST  threadid  %d\n", GetCurrentThreadId());
				CefString themeno = ds->data;
				self->browser_window_->GetClientHandler()->AddFinishedPaperToList(themeno, true);
			}
			else if (pcds->dwData == WM_DOWNLOADSPEED) {			 
				long speed = ds->value;
				_cprintf("  WM_DOWNLOADSPEED  speed  %d\n", speed);  
				myds::CDownloadService::GetInstance()->SetSpeedLimit(speed);
			}
			else if (pcds->dwData == WM_SCREENCAPTURE) {
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("uploadjs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 35);
				args->SetString(1, ds->data);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cwprintf(L"WM_SCREENCAPTURE::Send 35 %s\n", ds->data);
			}
			else if (pcds->dwData == WM_DDPICHANGED) {
				RECT wr = self->start_rect_;
				SetWindowPos(self->hwnd_, NULL, wr.left, wr.top, wr.right - wr.left,
					self->start_rect_.bottom - self->start_rect_.top, SWP_NOZORDER);
				if (LOGDEBUG)
				    _cprintf("DPI CHANGED window  %d   %d  %d  %d\n", wr.left, wr.top, wr.right, wr.bottom);
				RECT rect;
				GetClientRect(self->hwnd_, &rect);
				rect.right = self->start_rect_.right - self->start_rect_.left + rect.left;
				rect.bottom = self->start_rect_.bottom - self->start_rect_.top + rect.top;
				SetWindowPos(self->GetBrowser()->GetHost()->GetWindowHandle(), NULL, rect.left, rect.top, rect.right - rect.left,
					rect.bottom - rect.top, SWP_NOZORDER);
				if (LOGDEBUG)
				   _cprintf("DPI CHANGED window  %d   %d  %d  %d\n", rect.left, rect.top, rect.right, rect.bottom);
				break;
			} else if (pcds->dwData == WM_DROOTURL) {
				std::wstring  rooturl;
				rooturl.append(ds->data);
				if (LOGDEBUG) _cwprintf(L" ROOTURL   %s\n", rooturl.c_str() );
				int index =  rooturl.find(L",");
				if (index != -1) {
					std::wstring  firsturl = rooturl.substr(0, index);
					CefString  s;
					s.FromWString(firsturl);
					MainContext::Get()->SaveURootUrl(s.ToString());
					std::wstring  secondurl = rooturl.substr(index+1, rooturl.length() - index -1);
					s.clear();
					s.FromWString(secondurl);
					MainContext::Get()->SaveCommentDetailUrl(s.ToString());
					if (LOGDEBUG) _cwprintf(L"  first url:  %s            |        second url: %s \n", firsturl.c_str(), secondurl.c_str());
				}
			}
			else if (pcds->dwData == WM_NEWBROWSER) {
				MainContext::Get()->SaveTabId(ds->value);
                std::wstring  url;
                url.append(L"window.open('");
                url.append(ds->data);
                url.append(L"');");
                CefString csurl;
                csurl.FromWString(url);
                if (LOGDEBUG) _cwprintf(L"Create a new popup window  tid = %d  url = %s\n", ds->value, csurl.ToWString().c_str());
                MainContext::Get()->SavePopupType(MainContext::PopupType::poptabo);
                self->GetBrowser()->GetMainFrame()->ExecuteJavaScript(
	            csurl, "about:blank", 0);
			}
			else if (pcds->dwData == WM_PAPERPLAYING) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERPLAYING  [%s], %lld\n", s.ToWString().c_str(), paperid);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::PLAYING, self->GetBrowser());
			}
			else if (pcds->dwData == WM_PAPERPAUSEPLAY) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERPAUSEPLAY  %s, %lld\n", ds->data, paperid);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::PAUSEPLAY, self->GetBrowser());
			}
			else if (pcds->dwData == WM_PAPERDOWNLOADING) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERDOWNLOADING  %s\n", ds->data);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::DOWNLOADING, self->GetBrowser());
			}
			else if (pcds->dwData == WM_PAPERPAUSEDOWNLOAD) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERPAUSEDOWNLOAD  %s\n", ds->data);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::PAUSEDOWNLOAD, self->GetBrowser());
			}
			else if (pcds->dwData == WM_PAPERDOWNLOADED) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERDOWNLOADED  %s\n", ds->data);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::DOWNLOADED, self->GetBrowser());
			}
			else if (pcds->dwData == WM_PAPERDELETE) { // 1.9
				CefString s;
				s.FromWString(ds->data);
				int64 paperid = atoll(s.ToString().c_str());
				if (LOGDEBUG) _cwprintf(L" WM_PAPERDELETE  %s\n", ds->data);
				self->browser_window_->GetClientHandler()->UpdatePaperStatusFromBar(paperid, WallPaper::NOTDOWNLOADED, self->GetBrowser());
			}
			else if (pcds->dwData == WM_DELAYCLOSE) {
				self->Hide();
				SetParent(self->hwnd_, NULL);
				SetTimer(self->hwnd_, ID_DELAYCLOSE_TIMER, 5000, NULL); // time out for 5s
			}
			else if (pcds->dwData == WM_HASLOGINED) {
				if (LOGDEBUG) _cprintf("WM_HASLOGINED\n");
				UserManager::Get()->ReadUserToken();
				std::string info = UserManager::Get()->ReadUserInfo();			 
 
				if (MainContext::Get()->IsCinemaApp()) {
					CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("dramacalljs");
					CefRefPtr<CefListValue> args = msg->GetArgumentList();
					args->SetInt(0, 21);
					args->SetString(1, info);
					self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
					_cprintf("Send user infomation 21  to dramacalljs   \n" );
				}
				else {
					CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
					CefRefPtr<CefListValue> args = msg->GetArgumentList();
					args->SetInt(0, 20);
					args->SetString(1, info);
					self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
					_cprintf("Send user infomation 20 to parentCalljs  %s\n" );
				}	 
			}
			else if (pcds->dwData == WM_STOREPLAYPAPER) {
				CefString s;
				s.FromWString(ds->data);
				if (LOGDEBUG) _cprintf("receive WM_STOREPLAYPAPER  %s\n", s.ToString().c_str());
				self->browser_window_->GetClientHandler()->UpdatePlayingId(s);
				CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("localPaperCalljs");
				CefRefPtr<CefListValue> args = msg->GetArgumentList();
				args->SetInt(0, 27);
				args->SetString(1, s);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			}
		}
		break;

	case WM_DROPFILES:
	{
		if ( !UserManager::Get()->IsLogin() ) {
			if (LOGDEBUG) _cwprintf(L"WM_DROPFILES:: not login, send loging requests\n");
			COPYDATASTRUCT MyCDS;
			CEFHWMSG rec;
			MyCDS.dwData = WM_DPLEASELOGIN;
			MyCDS.cbData = sizeof(rec);
			MyCDS.lpData = &rec;
			SendMessage(MainContext::Get()->GetCallerHwnd(),
				WM_COPYDATA,
				NULL,
				(LPARAM)(LPVOID)&MyCDS);
			return 0;
		}
 

		HDROP  hdrop = (HDROP)(wParam);
		TCHAR filebuf[1024];
		DragQueryFile(hdrop, 0, filebuf, 1024);

		DWORD dwAttrib = GetFileAttributes(filebuf);

		CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("uploadjs");
		CefRefPtr<CefListValue> args = msg->GetArgumentList();
		CefRefPtr<CefDictionaryValue> dict = CefDictionaryValue::Create();
		CefString jsonString;

		if (!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {   // it is not directory
			_cprintf("WM_DROPFILES:: the dropped is not a directory.\n");
			std::wstring  videofile(filebuf);
			int index = videofile.find_last_of(L"\\");
			std::wstring filename = videofile.substr(index + 1,  videofile.length() - index -1);
			std::wstring path = videofile.substr(0, index);
			_cwprintf(L"filename is   %s, path is %s\n", filename.c_str(), path.c_str());
			
			if (filename.find(L".mp4") != -1 || filename.find(L".mov") != -1 || filename.find(L".avi") != -1 || filename.find(L".mkv") != -1)
			{
				TCHAR  sa[] = L"\\";
				TCHAR  ta[] = L"/";
				std::replace(path.begin(), path.end(), sa[0], ta[0]);
				dict->SetInt("themeType", 1);
				dict->SetString("src", filename);
				dict->SetString("resourcepath", path);
				CefRefPtr<CefValue> pValue = CefValue::Create();
				pValue->SetDictionary(dict);
				jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
				args->SetInt(0, 30);
				args->SetString(1, jsonString);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cwprintf(L"WM_DROPFILES::Send 30 %s\n", jsonString.ToWString().c_str());
			}
			else {
				args->SetInt(0, 36);
				args->SetString(1, "not directory");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			}
 
		}
		else {  // it is a directory
			std::wstring indexpath(filebuf);
			indexpath.append(L"\\").append(L"index.html");
			if (!PathFileExists(indexpath.c_str())) {
				_cprintf("WM_DROPFILES:: Can not find index.html.\n");
				args->SetInt(0, 36);
				args->SetString(1, "no index.html");
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
			}
			else {
				std::wstring s(filebuf);
				TCHAR  sa[] = L"\\";
				TCHAR  ta[] = L"/";
				std::replace(s.begin(), s.end(), sa[0], ta[0]);
				_cwprintf(L"WM_DROPFILES  %s\n", s.c_str());
 
				dict->SetInt("themeType", 2);
				dict->SetString("src", "index.html");
				dict->SetString("resourcepath", s);
				CefRefPtr<CefValue> pValue = CefValue::Create();
				pValue->SetDictionary(dict);
			    jsonString = CefWriteJSON(pValue, JSON_WRITER_DEFAULT);
				args->SetInt(0, 30);
				args->SetString(1, jsonString);
				self->GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
				if (LOGDEBUG) _cwprintf(L"WM_DROPFILES::Send 30 %s\n", jsonString.ToWString().c_str());
			}
		}

	}
		break;
	case WM_TEST:
		if ( false)
		{
			// Create a CefRequest for the specified URL.
			CefString  url;
			url.FromASCII("http://dev.upupoo.com/store/collection/b3fb95d29c5243d3adaffe6af05ab96f.htm");
			CefRefPtr<CefRequest> cef_request = CefRequest::Create();
			CefRequest::HeaderMap headers;
			headers.insert(std::make_pair("Content-Type", "text/plain"));
			headers.insert(std::make_pair("Accept", "text/plain"));

			cef_request->SetURL(url);
			cef_request->SetMethod("GET");
			//cef_request->SetHeaderMap(headers);

			// Callback to be executed on request completion.
			// It's safe to use base::Unretained() here because there is only one
			// RequestClient pending at any given time and we explicitly detach the
			// callback in the Handler destructor.

			//const RequestClient::Callback& request_callback =
			//	base::Bind(&RootWindowWin::OnRequestComplete,  self);

			// Create and start the new CefURLRequest.
			//CefRefPtr<CefURLRequest> urlrequest_ = CefURLRequest::Create(
			//	cef_request, new RequestClient( ), NULL);
			//CefURLRequest::Create(cef_request, request_callback, NULL);
			
		}
		break;

	case WM_MINSIZE:
		ShowWindow(self->hwnd_, SW_MINIMIZE);
		if (LOGDEBUG) _cprintf("SW_MINIMIZE ....\n");
		break; 
 
	case WM_INNERSHOW:
		_cprintf("receive WM_INNERSHOW\n");
		if (!self->is_showing_ ) {
			if (LOGDEBUG)  _cprintf("show it after onloadend  %d\n", self->tabid_);
			self->Show(ShowMode::ShowNormal);
			self->is_showing_ = true;
		}
		break;
	case WM_INNERCLOSE:
		_cprintf("close it\n");
		self->Close(true);
		break;

	case  WM_KEYDOWN:
		break;

	case WM_TIMER:
		if (wParam == ID_NET_TIMER) {
			HMODULE hModule = GetModuleHandleW(NULL);
			WCHAR curpath[MAX_PATH];
			GetModuleFileNameW(hModule, curpath, MAX_PATH);
			PathRemoveFileSpec(curpath);
			PathRemoveFileSpec(curpath);

			std::wstring errurl;
			errurl.append(curpath);
			errurl.append(L"//errornet//errornet.html");
 
			CefString  cerrurl;
			cerrurl.FromWString(errurl);
			if (LOGDEBUG)  _cwprintf(L"timer is out, here we go.  %s\n", cerrurl.ToString());
			KillTimer(self->hwnd_, ID_NET_TIMER);
			self->GetBrowser()->GetMainFrame()->LoadURL(cerrurl);
		}
		else if (wParam == ID_LOGIN_TIMER) {
			self->Close(true);
		}
		else if (wParam == ID_DOWNLOAD_TIMER) {
			KillTimer(self->hwnd_, ID_DOWNLOAD_TIMER); 
			if (LOGDEBUG) _cprintf("ID_DOWNLOAD_TIMER\n");
				 
		  }
		else if (wParam == ID_LOADJS_TIMER) {
			{
				KillTimer(self->hwnd_, ID_LOADJS_TIMER);
				std::wstring jsfile = self->browser_window_->GetClientHandler()->GetLoadJs();
				std::ifstream t(jsfile);
				std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
				if (LOGDEBUG) {
					_cwprintf(L"ID_LOADJS_TIMER ----%s  load js\n", jsfile.c_str());
					_cprintf("[%s]\n", str.c_str());
				}	 

				self->GetBrowser()->GetMainFrame()->ExecuteJavaScript(str,
					"about:blank", 0);
				t.close();
			}
		}
		else if (wParam == ID_DELAYCLOSE_TIMER) {
			KillTimer(self->hwnd_, ID_DELAYCLOSE_TIMER);
			self->Close(true);
		}
		else  if (wParam == ID_DELAYSHOW_TIMER) {
			_cprintf("delay timer show\n"); 
			if (!self->is_showing_  && MainContext::Get()->IsShow()) {
				if (LOGDEBUG)  _cprintf("show it after onloadend\n");
				self->Show(ShowMode::ShowNormal);
				self->is_showing_ = true;
			}
			KillTimer(self->hwnd_, ID_DELAYSHOW_TIMER);
		}
		break;

	case WM_NCHITTEST:
	{
      LRESULT hit = DefWindowProc(hWnd, message, wParam, lParam);
      if (hit == HTCLIENT) {
        POINTS points = MAKEPOINTS(lParam);
        POINT point = {points.x, points.y};
        ::ScreenToClient(hWnd, &point);
        if (::PtInRegion(self->draggable_region_, point.x, point.y)) {
          // If cursor is inside a draggable region return HTCAPTION to allow
          // dragging.
          return HTCAPTION;
        }
      }
      return hit;
    }

    case WM_NCDESTROY:
      // Clear the reference to |self|.
      SetUserDataPtr(hWnd, NULL);
      self->hwnd_ = NULL;
      self->OnDestroyed();
      return 0;
  }

  return DefWindowProc(hWnd, message, wParam, lParam);
}

void RootWindowWin::OnPaint() {
  PAINTSTRUCT ps;
  BeginPaint(hwnd_, &ps);
  EndPaint(hwnd_, &ps);
}

void RootWindowWin::OnFocus() {
  if (browser_window_)
    browser_window_->SetFocus(true);
}

void RootWindowWin::OnSize(bool minimized) {
  if (minimized) {
    // Notify the browser window that it was hidden and do nothing further.
    if (browser_window_)
      browser_window_->Hide();
    return;
  }

  if (browser_window_)
    browser_window_->Show();

  RECT rect;
  GetClientRect(hwnd_, &rect);

  if (with_controls_) {
    static int button_width = GetButtonWidth();
    static int urlbar_height = GetURLBarHeight();

    // Resize the window and address bar to match the new frame size.
    rect.top += urlbar_height;

    int urloffset = rect.left + button_width * 4;

    // |browser_hwnd| may be NULL if the browser has not yet been created.
    HWND browser_hwnd = NULL;
    if (browser_window_)
      browser_hwnd = browser_window_->GetWindowHandle();

    if (browser_hwnd) {
      // Resize both the browser and the URL edit field.
      HDWP hdwp = BeginDeferWindowPos(2);
      hdwp =
          DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset, 0,
                         rect.right - urloffset, urlbar_height, SWP_NOZORDER);
      hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL, rect.left, rect.top,
                            rect.right - rect.left, rect.bottom - rect.top,
                            SWP_NOZORDER);
      BOOL result = EndDeferWindowPos(hdwp);
      ALLOW_UNUSED_LOCAL(result);
      DCHECK(result);
    } else {
      // Resize just the URL edit field.
      SetWindowPos(edit_hwnd_, NULL, urloffset, 0, rect.right - urloffset,
                   urlbar_height, SWP_NOZORDER);
    }
  } else if (browser_window_) {
    // Size the browser window to the whole client area.
    browser_window_->SetBounds(0, 0, rect.right, rect.bottom);
	if (LOGDEBUG) _cprintf("onsize    %d  %d\n", rect.right, rect.bottom);
  }
}

void RootWindowWin::OnMove() {
  // Notify the browser of move events so that popup windows are displayed
  // in the correct location and dismissed when the window moves.
  CefRefPtr<CefBrowser> browser = GetBrowser();
  if (browser)
    browser->GetHost()->NotifyMoveOrResizeStarted();
}

bool RootWindowWin::OnEraseBkgnd() {
  // Erase the background when the browser does not exist.
  return (GetBrowser() == NULL);
}

bool RootWindowWin::OnCommand(UINT id) {
  if (id >= ID_TESTS_FIRST && id <= ID_TESTS_LAST) {
    delegate_->OnTest(this, id);
    return true;
  }

  switch (id) {
    case IDM_ABOUT:
      OnAbout();
      return true;
    case IDM_EXIT:
      delegate_->OnExit(this);
      return true;
    case ID_FIND:
      OnFind();
      return true;
    case IDC_NAV_BACK:  // Back button
      if (CefRefPtr<CefBrowser> browser = GetBrowser())
        browser->GoBack();
      return true;
    case IDC_NAV_FORWARD:  // Forward button
      if (CefRefPtr<CefBrowser> browser = GetBrowser())
        browser->GoForward();
      return true;
    case IDC_NAV_RELOAD:  // Reload button
	  if (CefRefPtr<CefBrowser> browser = GetBrowser())
		 browser->Reload();

	//  UserManager::Get()->DownLoadUserIcon("http://f.hiphotos.baidu.com/image/pic/item/503d269759ee3d6db032f61b48166d224e4ade6e.jpg");
	  if ( false )  // Set  winddown transparent
	{
		CefRefPtr<CefBrowser> browser = GetBrowser();
		if (LOGDEBUG)  _cprintf("set transparent\n");

		LONG style = GetWindowLong(hwnd_, GWL_EXSTYLE);
		style = style | WS_EX_LAYERED;
		SetWindowLong(hwnd_, GWL_EXSTYLE, style);
		SetLayeredWindowAttributes(hwnd_, RGB(0, 0, 0), 100, LWA_ALPHA);

	}
		if ( false)
	{
		//fxf test
		PAINTSTRUCT ps;
		HDC hdc = BeginPaint (hwnd_, &ps);
		EnumDisplayMonitors(hdc, NULL, (MONITORENUMPROC)MyPaintEnumProc, 0);
		EndPaint(hwnd_, &ps);
		//fxf end
	}

      return true;
    case IDC_NAV_STOP:  // Stop button
      if (CefRefPtr<CefBrowser> browser = GetBrowser())
        browser->StopLoad();
      return true;
  }
  return false;
}

void RootWindowWin::OnFind() {
  if (find_hwnd_) {
    // Give focus to the existing find dialog.
    ::SetFocus(find_hwnd_);
    return;
  }

  // Configure dialog state.
  ZeroMemory(&find_state_, sizeof(find_state_));
  find_state_.lStructSize = sizeof(find_state_);
  find_state_.hwndOwner = hwnd_;
  find_state_.lpstrFindWhat = find_buff_;
  find_state_.wFindWhatLen = sizeof(find_buff_);
  find_state_.Flags = FR_HIDEWHOLEWORD | FR_DOWN;

  // Create the dialog.
  find_hwnd_ = FindText(&find_state_);

  // Override the dialog's window procedure.
  find_wndproc_old_ = SetWndProcPtr(find_hwnd_, FindWndProc);

  // Associate |self| with the dialog.
  SetUserDataPtr(find_hwnd_, this);
}

void RootWindowWin::OnFindEvent() {
  CefRefPtr<CefBrowser> browser = GetBrowser();

  if (find_state_.Flags & FR_DIALOGTERM) {
    // The find dialog box has been dismissed so invalidate the handle and
    // reset the search results.
    if (browser) {
      browser->GetHost()->StopFinding(true);
      find_what_last_.clear();
      find_next_ = false;
    }
  } else if ((find_state_.Flags & FR_FINDNEXT) && browser) {
    // Search for the requested string.
    bool match_case = ((find_state_.Flags & FR_MATCHCASE) ? true : false);
    const std::wstring& find_what = find_buff_;
    if (match_case != find_match_case_last_ || find_what != find_what_last_) {
      // The search string has changed, so reset the search results.
      if (!find_what.empty()) {
        browser->GetHost()->StopFinding(true);
        find_next_ = false;
      }
      find_match_case_last_ = match_case;
      find_what_last_ = find_buff_;
    }

    browser->GetHost()->Find(0, find_what,
                             (find_state_.Flags & FR_DOWN) ? true : false,
                             match_case, find_next_);
    if (!find_next_)
      find_next_ = true;
  }
}

void RootWindowWin::OnAbout() {
  // Show the about box.
  DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd_,
            AboutWndProc);
}

bool RootWindowWin::OnClose() {
  if (browser_window_ && !browser_window_->IsClosing()) {
	 SetParent(hwnd_, NULL);
    CefRefPtr<CefBrowser> browser = GetBrowser();
    if (browser) {
      // Notify the browser window that we would like to close it. This
      // will result in a call to ClientHandler::DoClose() if the
      // JavaScript 'onbeforeunload' event handler allows it.
      browser->GetHost()->CloseBrowser(false);

      // Cancel the close.
      return true;
    }
  }

  // Allow the close.
  return false;
}

void RootWindowWin::OnDestroyed() {
  window_destroyed_ = true;
  NotifyDestroyedIfDone();
}

void RootWindowWin::OnBrowserCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_MAIN_THREAD();
  if (is_popup_) {
    // For popup browsers create the root window once the browser has been
    // created.
    CreateRootWindow(CefBrowserSettings());
  } else {
    // Make sure the browser is sized correctly.
    OnSize(false);
  }
}

void RootWindowWin::OnBrowserWindowDestroyed() {
  REQUIRE_MAIN_THREAD();

  browser_window_.reset();

  if (!window_destroyed_) {
    // The browser was destroyed first. This could be due to the use of
    // off-screen rendering or execution of JavaScript window.close().
    // Close the RootWindow.
    Close(true);
  }

  browser_destroyed_ = true;
  NotifyDestroyedIfDone();
}

void RootWindowWin::OnSetAddress(const std::string& url) {
  REQUIRE_MAIN_THREAD();
  //if (LOGDEBUG)  _cprintf("Address     %s\n", url.c_str());
  if (edit_hwnd_)
    SetWindowText(edit_hwnd_, CefString(url).ToWString().c_str());
}

void RootWindowWin::OnSetTitle(const std::string& title) {
  REQUIRE_MAIN_THREAD();

  if (MainContext::Get()->IsAfterSomeApp() || MainContext::Get()->IsNewTabApp() ) {
	  COPYDATASTRUCT MyCDS;
	  CEFHWMSG rec;
	  rec.value = tabid_;
	  swprintf(rec.data, 255, L"%s", CefString(title).ToWString().c_str());
	  MyCDS.dwData = WM_DTITLECHANGE;
	  MyCDS.cbData = sizeof(rec);
	  MyCDS.lpData = &rec;
	   
	  SendMessage(MainContext::Get()->GetCallerHwnd(),
		  WM_COPYDATA,
		  (WPARAM)tabid_,
		  (LPARAM)(LPVOID)&MyCDS);
	  _cwprintf(L"title  tabid = %d -------------  [%s] \n", tabid_, CefString(title).ToWString().c_str());
  }
  
  if (hwnd_) {
	  SetWindowText(hwnd_, CefString(title).ToWString().c_str());
  }    
  
}


void RootWindowWin::OnSetFullscreen(bool fullscreen) {
  REQUIRE_MAIN_THREAD();

  CefRefPtr<CefBrowser> browser = GetBrowser();
  if (browser) {
    scoped_ptr<window_test::WindowTestRunnerWin> test_runner(
        new window_test::WindowTestRunnerWin());
    if (fullscreen)
      test_runner->Maximize(browser);
    else
      test_runner->Restore(browser);
  }
}

void RootWindowWin::PushPaperLocal(WallPaper &paper) {
	paper_local_array_.push_back(paper);
}

WallPaper * RootWindowWin::FindPaperLocal(int paperid) {
	for (int i = 0; i < (int)paper_local_array_.size(); i++) {
		if (paper_local_array_[i].paperid_ == paperid)  return &paper_local_array_[i];
	}
	return 0;
}

void RootWindowWin::OnSetLoadingState(bool isLoading,
                                      bool canGoBack,
                                      bool canGoForward) {
  REQUIRE_MAIN_THREAD();

  if (with_controls_) {
    EnableWindow(back_hwnd_, canGoBack);
    EnableWindow(forward_hwnd_, canGoForward);
    EnableWindow(reload_hwnd_, !isLoading);
    EnableWindow(stop_hwnd_, isLoading);
    EnableWindow(edit_hwnd_, TRUE);
  }
  //COPYDATASTRUCT MyCDS;
  //CEFHWMSG MyRec;
  int  state = 0x00;
  int canback=0;
  int canforward = 0;
  if (canGoBack) {
	  state |= 0x01;
	  canback = 1;
  }
  if (canGoForward) {
	  state |= 0x02;
	  canforward = 1;
  }

  std::stringstream s;
  s << canforward <<canback ;
  CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create("parentCalljs");
  CefRefPtr<CefListValue>  args = msg->GetArgumentList();
  args->SetInt(0, 46);
  args->SetString(1, s.str());
  GetBrowser()->SendProcessMessage(PID_RENDERER, msg);
	   
  CefRefPtr<CefProcessMessage> msg2 = CefProcessMessage::Create("dramacalljs");
  CefRefPtr<CefListValue>  args2 = msg2->GetArgumentList();
  args2->SetInt(0, 46);
  args2->SetString(1, s.str());
  GetBrowser()->SendProcessMessage(PID_RENDERER, msg2);

  if (LOGDEBUG) _cprintf("Send load state %s\n", s.str().c_str());
  //MyRec.value = (DWORD)state;
  //MyCDS.dwData = WM_DLOADSTATE;
  //MyCDS.cbData = sizeof(MyRec);
  //MyCDS.lpData = &MyRec;

  //SendMessage(MainContext::Get()->GetCallerHwnd(),
	 // WM_COPYDATA,
	 // (WPARAM)tabid_,
	 // (LPARAM)(LPVOID)&MyCDS);
  //_cprintf("Loading state changed   tid=%d  state = %d\n", tabid_, state);
}

namespace {

LPCWSTR kParentWndProc = L"CefParentWndProc";
LPCWSTR kDraggableRegion = L"CefDraggableRegion";

LRESULT CALLBACK SubclassedWindowProc(HWND hWnd,
                                      UINT message,
                                      WPARAM wParam,
                                      LPARAM lParam) {
  WNDPROC hParentWndProc =
      reinterpret_cast<WNDPROC>(::GetPropW(hWnd, kParentWndProc));
  HRGN hRegion = reinterpret_cast<HRGN>(::GetPropW(hWnd, kDraggableRegion));

  if (message == WM_NCHITTEST) {
    LRESULT hit = CallWindowProc(hParentWndProc, hWnd, message, wParam, lParam);
    if (hit == HTCLIENT) {
      POINTS points = MAKEPOINTS(lParam);
      POINT point = {points.x, points.y};
      ::ScreenToClient(hWnd, &point);
      if (::PtInRegion(hRegion, point.x, point.y)) {
        // Let the parent window handle WM_NCHITTEST by returning HTTRANSPARENT
        // in child windows.
        return HTTRANSPARENT;
      }
    }
    return hit;
  }

  return CallWindowProc(hParentWndProc, hWnd, message, wParam, lParam);
}

void SubclassWindow(HWND hWnd, HRGN hRegion) {
  HANDLE hParentWndProc = ::GetPropW(hWnd, kParentWndProc);
  if (hParentWndProc) {
    return;
  }

  SetLastError(0);
  LONG_PTR hOldWndProc = SetWindowLongPtr(
      hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SubclassedWindowProc));
  if (hOldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
    return;
  }

  ::SetPropW(hWnd, kParentWndProc, reinterpret_cast<HANDLE>(hOldWndProc));
  ::SetPropW(hWnd, kDraggableRegion, reinterpret_cast<HANDLE>(hRegion));
}

void UnSubclassWindow(HWND hWnd) {
  LONG_PTR hParentWndProc =
      reinterpret_cast<LONG_PTR>(::GetPropW(hWnd, kParentWndProc));
  if (hParentWndProc) {
    LONG_PTR hPreviousWndProc =
        SetWindowLongPtr(hWnd, GWLP_WNDPROC, hParentWndProc);
    ALLOW_UNUSED_LOCAL(hPreviousWndProc);
    DCHECK_EQ(hPreviousWndProc,
              reinterpret_cast<LONG_PTR>(SubclassedWindowProc));
  }

  ::RemovePropW(hWnd, kParentWndProc);
  ::RemovePropW(hWnd, kDraggableRegion);
}

BOOL CALLBACK SubclassWindowsProc(HWND hwnd, LPARAM lParam) {
  SubclassWindow(hwnd, reinterpret_cast<HRGN>(lParam));
  return TRUE;
}

BOOL CALLBACK UnSubclassWindowsProc(HWND hwnd, LPARAM lParam) {
  UnSubclassWindow(hwnd);
  return TRUE;
}

}  // namespace


void RootWindowWin::OnSetDraggableRegions(
    const std::vector<CefDraggableRegion>& regions) {
  REQUIRE_MAIN_THREAD();

  // Reset draggable region.
  ::SetRectRgn(draggable_region_, 0, 0, 0, 0);

  // Determine new draggable region.
  std::vector<CefDraggableRegion>::const_iterator it = regions.begin();
  for (; it != regions.end(); ++it) {
    HRGN region = ::CreateRectRgn(it->bounds.x, it->bounds.y,
                                  it->bounds.x + it->bounds.width,
                                  it->bounds.y + it->bounds.height);
    ::CombineRgn(draggable_region_, draggable_region_, region,
                 it->draggable ? RGN_OR : RGN_DIFF);
    ::DeleteObject(region);
  }

  // Subclass child window procedures in order to do hit-testing.
  // This will be a no-op, if it is already subclassed.
  if (hwnd_) {
    WNDENUMPROC proc =
        !regions.empty() ? SubclassWindowsProc : UnSubclassWindowsProc;
    ::EnumChildWindows(hwnd_, proc,
                       reinterpret_cast<LPARAM>(draggable_region_));
  }
}

void RootWindowWin::NotifyDestroyedIfDone() {
  // Notify once both the window and the browser have been destroyed.
  if (window_destroyed_ && browser_destroyed_)
    delegate_->OnRootWindowDestroyed(this);
}

void RequestTask::Execute()   {
	_cprintf("RequestTask Execute......\n");
 
}

//定义窗口函数
LRESULT CALLBACK MoveWindowProc(
	HWND hwnd,
	UINT uMsg,
	WPARAM wParam,
	LPARAM IParam
)
{

	switch (uMsg)
	{
	case WM_CREATE:
	{
		HBRUSH brush = CreateSolidBrush(RGB(255, 180, 0));
		SetClassLongPtr(hwnd, GCLP_HBRBACKGROUND, (LONG)brush);
		SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
		//Make this window 70% alpha
		SetLayeredWindowAttributes(hwnd, RGB(255, 180, 0), (255 * 70) / 100, LWA_COLORKEY);
	}
	break;
 
	case WM_PAINT:
	{
		//_cprintf("WM_PAINT movable\n");
		RECT secondbackground;
		HDC hdc = GetDC(hwnd);
		//SetRect(&secondbackground, 3, 3, 297, 495);
		GetClientRect(hwnd, &secondbackground);
		SetDCPenColor(hdc, RGB(255, 0, 0));    
		Rectangle(hdc, secondbackground.left, secondbackground.top, secondbackground.right, secondbackground.bottom);
		secondbackground.left += 5;
		secondbackground.top += 5;
		secondbackground.bottom -= 5;
		secondbackground.right -= 5;
		FillRect(hdc, &secondbackground, CreateSolidBrush(RGB(255, 180, 0)));
		//SetRect(&titlebox, 20, 20, 278, 45);
		//FillRect(hdc, &titlebox, hYellow);
		ReleaseDC(hwnd, hdc);
	}
 
		break;

	case WM_MOUSEMOVE:
		break;

	case WM_CLOSE:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, uMsg, wParam, IParam);
	}
	return  DefWindowProc(hwnd, uMsg, wParam, IParam);
}



float RootWindowWin::GetDpiScale() {
	HDC screen = GetDC(0);
	int dpiX = GetDeviceCaps(screen, LOGPIXELSX);
	//int dpiY = GetDeviceCaps(screen, LOGPIXELSY);
	float scale = dpiX * 1.0 / 96;
	if ( LOGDEBUG) _cwprintf(L"  scale= %.1f \n",  scale);
	return scale;
}
}  // namespace client
